﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using System;
using Object = UnityEngine.Object;

namespace HHHFramework
{
    public interface ISpawnPool
    {
        T Allocate<T>(string assetName, string assetBundleName = null) where T : Object;
        void Push<T>(T obj) where T : Object;

        void AsyncAllocate<T>(string assetName, string assetBundleName = null, Action<T> callback = null) where T : Object;
    }
    [Serializable]
    /// <summary>
    /// 根据类型添加一个pool Spawn
    /// </summary>
    public class SpawnPool: UnityEngine.Object, ISpawnPool
    {
        public Stack<Object> poolEntityStack = new Stack<Object>();
        ResLoad resLoad;
        public void SpawnPoolCreate<T>(string assetName, string assetBundleName = null, int count = 1) where T : Object
        {
            resLoad = new ResLoad();
            for (int i = 0; i < count; i++)
            {
               T  res = resLoad.LoadSync<T>(assetName, assetBundleName);

                poolEntityStack.Push(UnityEngine.GameObject.Instantiate<T>(res));
            }
     
        }
        public T Allocate<T>(string assetName, string assetBundleName = null) where T : Object
        {
            T returnRes;
         
            if (poolEntityStack.Count == 0)
            {
                T res = resLoad.LoadSync<T>(assetName, assetBundleName);
                returnRes = UnityEngine.GameObject.Instantiate<T>(res);
                return returnRes;
            }
            else
            {
                return poolEntityStack.Pop() as T;
            }
        }
        public void AsyncAllocate<T>(string assetName, string assetBundleName = null, Action<T> callback = null) where T : Object
        {
            if (poolEntityStack.Count == 0)
            {

                resLoad.LoadAsync<T>(assetName, assetBundleName, (t1) =>
                {
                    T objectIns = UnityEngine.GameObject.Instantiate<T>(t1);
                    callback?.Invoke(objectIns);
                });
            }
            else
            {
                callback?.Invoke(poolEntityStack.Pop() as T);
            }
        }

        public void Push<T>(T res) where T : Object {
            if (!poolEntityStack.Contains(res)) { poolEntityStack.Push(res); }
          
        }

        public void ReleaseSpawnPool(){
            resLoad.ReleaseAll();
        }

    }

  

}


 


